from src.model.cash_trade import CashTradeModel
from src.model.asset_balance import AssetBalanceModel
from binance.client import Client
from binance import exceptions


class API:
    def __init__(self, options):
        self.exchangeInfoData = None
        self.client = options.get('client', None)
        self.chatbot = options.get('chatbot', None)
        self.logger = options.get('logger', None)

    def getKLines(self, symbol, interval=Client.KLINE_INTERVAL_30MINUTE):
        return self.client.get_klines(symbol=symbol, interval=interval)

    def avgPrice(self, symbol):
        # 获取当前市场均价
        return self.client.get_avg_price(symbol=symbol)

    def exchangeInfo(self):
        ''' 市场交易信息 '''
        if self.exchangeInfoData is None:
            res = self.client.get_exchange_info()
            self.exchangeInfoData = res
        else:
            res = self.exchangeInfoData
        return res

    def getAssetBalance(self, asset):
        try:
            res = self.client.get_asset_balance(asset=asset)
        except Exception as e:
            message = 'getAssetBalance,msg:{}'.format(e)
            self.chatbot.sendmsg(message, tag='getAssetBalance')
            raise
        return AssetBalanceModel(res)

    def getMyTrades(self, symbol, limit=1):
        ''' 获取我交易信息
        '''
        try:
            res = self.client.get_my_trades(symbol=symbol, limit=limit)
            return res[0]
        except exceptions.BinanceAPIException as e:
            self.chatbot.sendmsg(e, tag='getMyTrades')
            raise

    def getOrder(self, symbol, orderId):
        try:
            return self.client.get_order(symbol=symbol, orderId=orderId)
        except exceptions.BinanceAPIException as e:
            self.chatbot.sendmsg(e, tag='getOrder')
            raise

    def cancelOrder(self, symbol, orderId):
        ''' 取消订单
        :param symbol 交易对
        :param orderId 被取消订单id
        return result
        '''
        try:
            res = self.client.cancel_order(symbol=symbol, orderId=orderId)
            orderStatus = res.get('status')
            if orderStatus == 'CANCELED':
                message = '订单取消成功{}'.format(res)
                flag = True
            else:
                message = '订单取消失败{}'.format(res)
                flag = False
            self.chatbot.sendmsg(message, tag='cancelOrder')
            return flag
        except exceptions.BinanceAPIException as e:
            self.chatbot.sendmsg(e, tag='cancelOrder')
            raise

    def getPrice(self, symbol):
        '''获当前市价'''
        try:
            res = self.client.get_order_book(symbol=symbol, limit=5)
            bids = res['asks'][0][0]  # 买
            bids_old = float(bids)
            new_list = list(str(bids_old))
            end_bids = int(new_list[-1]) + 1
            new_list.pop()
            new_list.append(str(end_bids))
            old_price = ''.join(new_list)
            self.logger.info('getPrice,msg:{msg}'.format(msg=bids_old))
            return round(float(old_price), 2)
        except Exception as e:
            message = 'getPrice,msg:{msg}'.format(msg=e)
            self.chatbot.sendmsg(message, tag='getPrice')
            raise

    def orderLimit(self, symbol, side, quantity, price):
        ''' 下订单
        :param side 订单类型 SELL|BUY
        :param symbol 交易对 BCHUSDT
        :param quantity 数量
        :param price 价格
        return result
        '''

        message = '{side}单进行下单,symbol:{symbol},quantity:{quantity},price:{price}'.format(
            symbol=symbol, side=side, quantity=quantity, price=price)
        self.logger.info(message)
        try:
            res = self.client.order_limit(symbol=symbol,
                                          side=side,
                                          quantity=quantity,
                                          price=price)
        except exceptions.BinanceAPIException as e:
            self.chatbot.sendmsg(e, tag='order')
            raise

        message = '{side}单下单成功{res}'.format(side=side, res=res)
        self.chatbot.sendmsg(message, tag='order')
        # 订单数据转换成模型数据
        return CashTradeModel(res)

    def getTicker(self, symbol):
        try:
            return self.client.get_ticker(symbol=symbol)
        except exceptions.BinanceAPIException as e:
            self.chatbot.sendmsg(e, tag='getMyTrades')
            raise
